/*
 * 现在是时候将数据保存到数据库了。Orchard Core 使用 YesSql 将数据存储到数据库中，
 * 这是一种为关系型数据库提供文档数据库接口的工具。简单来说，你需要像设计文档数据库一样设计数据库，
 * 但数据实际存储在你喜欢的 SQL 数据库中。更多信息请参考：https://github.com/sebastienros/yessql。
 *
 * 本示例演示如何在不使用 Orchard Core 内容管理特性和实践的情况下，
 * 将简单数据存储到数据库并进行查询（即可以存储非 Orchard Core 内容项的数据）。
 *
 * 这里的演示非常简单，更多高级特性可参考后续内容和 YesSql 文档。
 */

using Ruitu.Edu.TrainingDemo.Indexes;
using Ruitu.Edu.TrainingDemo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.ModelBinding;
using OrchardCore.DisplayManagement.Notify;
using System.Collections.Generic;
using System.Threading.Tasks;
using YesSql;

namespace Ruitu.Edu.TrainingDemo.Controllers;

/// <summary>
/// 数据库存储控制器 - 演示如何使用 YesSql 存储和查询自定义数据
/// 
/// 主要用途：
/// - 演示如何将自定义对象存储到数据库
/// - 展示如何使用索引进行高效查询
/// - 不依赖 Orchard Core 内容管理特性
/// 
/// 使用场景：
/// - 需要存储非内容项的业务数据
/// - 需要自定义数据结构和查询
/// 
/// 设计原因：
/// - 利用 YesSql 的文档数据库特性
/// - 展示索引与查询的结合
/// 
/// 设计模式：
/// - 依赖注入模式：通过构造函数注入服务
/// - 索引模式：通过索引提升查询效率
/// </summary>
public sealed class DatabaseStorageController : Controller
{
    private readonly ISession _session;
    private readonly IDisplayManager<Book> _bookDisplayManager;
    private readonly INotifier _notifier;
    private readonly IHtmlLocalizer H;
    private readonly IUpdateModelAccessor _updateModelAccessor;

    /// <summary>
    /// 构造函数 - 初始化依赖服务
    /// </summary>
    public DatabaseStorageController(
        ISession session,
        IDisplayManager<Book> bookDisplayManager,
        INotifier notifier,
        IHtmlLocalizer<DatabaseStorageController> htmlLocalizer,
        IUpdateModelAccessor updateModelAccessor)
    {
        _session = session;
        _bookDisplayManager = bookDisplayManager;
        _notifier = notifier;
        _updateModelAccessor = updateModelAccessor;
        H = htmlLocalizer;
    }

    /// <summary>
    /// 创建图书页面 - 显示带有创建按钮的页面
    /// 访问路径：/Ruitu.Edu.TrainingDemo/DatabaseStorage/CreateBooks
    /// </summary>
    [HttpGet]
    public IActionResult CreateBooks() => View();

    /// <summary>
    /// 创建图书 POST 操作 - 将演示如何批量保存数据到数据库
    /// </summary>
    [HttpPost, ActionName(nameof(CreateBooks)), ValidateAntiForgeryToken]
    public async Task<IActionResult> CreateBooksPost()
    {
        // 演示：创建 3 本图书并逐个保存到数据库。
        // 注意：如需直接操作数据库可注入 IDbConnectionAccessor。
        // 存储到文档后还需建立索引以便后续查询。
        // 下一站：Indexes/BookIndex.cs
        foreach (var book in CreateDemoBooks())
        {
            await _session.SaveAsync(book);
        }

        await _notifier.InformationAsync(H["Books have been created in the database."]);

        return RedirectToAction(nameof(CreateBooks));
    }

    /// <summary>
    /// 查询并显示 J.K. Rosenzweig 所著图书
    /// 访问路径：/Ruitu.Edu.TrainingDemo/DatabaseStorage/JKRosenzweigBooks
    /// </summary>
    public async Task<IActionResult> JKRosenzweigBooks()
    {
        // 使用 ISession 查询图书数据。
        var jkRosenzweigBooks = await _session
            .Query<Book, BookIndex>()
            .Where(index => index.Author == "J.K. (Joanne) Rosenzweig")
            .ListAsync();

        // 将查询到的图书对象转换为显示形状。
        var bookShapes = await jkRosenzweigBooks.AwaitEachAsync(async book =>
            await _bookDisplayManager.BuildDisplayAsync(book, _updateModelAccessor.ModelUpdater));

        // 可查看 Views/DatabaseStorage/JKRosenzweigBooks.cshtml
        return View(bookShapes);
    }

    // 训练部分结束：文档数据库与索引记录存储
    // 下一站：Models/PersonPart.cs

    /// <summary>
    /// 创建演示用图书数据
    /// </summary>
    private static Book[] CreateDemoBooks() =>
        [
            new Book
            {
                CoverPhotoUrl = "/Ruitu.Edu.TrainingDemo/images/HarryPotter.jpg",
                Title = "Harry Potter and The Sorcerer's Stone",
                Author = "J.K. (Joanne) Rosenzweig",
                Description = "Harry hasn't had a birthday party in eleven years - but all that is about to " +
                    "change when a mysterious letter arrives with an invitation to an incredible place.",
            },
            new Book
            {
                Title = "Fantastic Beasts and Where To Find Them",
                Author = "J.K. (Joanne) Rosenzweig",
                Description = "With his magical suitcase in hand, Magellanic Newt Scamander arrives in New " +
                    "York in 1926 for a brief stopover. However, when the suitcase is misplaced and some of his " +
                    "fantastic beasts escape, there will be trouble for everyone.",
            },
            new Book
            {
                Title = "The Hunger Games",
                Author = "Suzanne Collins",
                Description = "The nation of Panay, formed from a post-apocalyptic North America, is a country " +
                    "that consists of a wealthy Capitol region surrounded by 12 poorer districts.",
            },
        ];
}
